﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.BuyerScarletInformation.Dto;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.BuyerScarletInformation
{
    public class BuyerScarletInformationService : BPMReportPlatformAppService, IBuyerScarletInformationService
    {
        private readonly SqlSugarClient _db, _dbPlatform, _dbProcess, _dbEngine;
        // private readonly ILogger<BuyerScarletInformationService> _logger;
        private readonly INPRestHttpHelper _httpClient;
        private readonly IBPMUtilsAppService _bPmUtilsApp;
        private readonly IBPMPlatformAppService _iBpmPlatformApp;

        private readonly string _esbUrl;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        /// <param name="httpClient"></param>
        /// <param name="configuration"></param>
        /// <param name="bPmUtilsApp"></param>
        /// <param name="iBpmPlatformApp"></param>
        public BuyerScarletInformationService(ISqlSugarAppService sqlSugarAppService, INPRestHttpHelper httpClient, IConfiguration configuration, IBPMUtilsAppService bPmUtilsApp, IBPMPlatformAppService iBpmPlatformApp)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbProcess = sqlSugarAppService.GetProcessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _httpClient = httpClient;
            _esbUrl = configuration["Nippon:ESB:ESBCommApi"];
            _bPmUtilsApp = bPmUtilsApp;
            _iBpmPlatformApp = iBpmPlatformApp;
        }


        public async Task<PagedResultDto<GetBuyerScarletInformationOutput>> GetAllAsync(GetBuyerScarletInformationInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBpmPlatformApp.GetUserAsync(CurrentUser.UserName);
            listViewDto.ForEach(x => { x.Url = _bPmUtilsApp.GetProcessUrl(x.InstanceNumber, userId); });

            //返回结果
            return new PagedResultDto<GetBuyerScarletInformationOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetBuyerScarletInformationOutput>> ExportAsync(GetBuyerScarletInformationInput input)
        {
            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        public async Task<ISugarQueryable<GetBuyerScarletInformationOutput>> GetQueryable(GetBuyerScarletInformationInput input)
        {
            var currentUserId = Guid.Empty;
            var instanceIds = new List<string>();
            if (!input.IsQueryAll)
            {
                var currentUserDto = await _dbPlatform.Queryable<Users>()
                    .Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).FirstAsync();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                    instanceIds = await _dbEngine.Queryable<Tasks, Instances>((t, i) => t.InstanceNumber == i.Number)
                        .Where((t, i) => t.UserId == currentUserId.ToString() && (i.ProcessName == "购方红字信息表" || i.ProcessName == "关企间退货红冲流程"))
                        .Select((t, i) => t.InstanceNumber).Distinct().ToListAsync();
                }
            }


            var listQueryable = _db.Queryable<BuyerScarletInformationFormDetail, BuyerScarletInformationFormHeader, SendRedLetterInvoiceMain, BusinessProcessesNew>(
                (a, b, c, d) => new JoinQueryInfos(JoinType.Left, a.InstanceNumber == b.InstanceNumber, 
                JoinType.Left, a.ApplySerialNo == c.SellerNumber, 
                JoinType.Left, a.InstanceNumber == d.InstanceId))

            .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber),
                (a, b, c, d) => a.InstanceNumber == input.InstanceNumber)
            .WhereIF(!input.OrderStatus.IsNullOrEmpty(),
                (a, b, c, d) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), d.ProcessStatusCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName),
                (a, b, c, d) => d.StartUserName.Contains(input.AddUserName))
            .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                (a, b, c, d) => d.StartTime >= input.StartCreationTime &&
                                d.StartTime <= input.EndCreationTime)
            .WhereIF(!input.IsQueryAll,
                (a, b, c, d) => d.StartUserId == (currentUserId))

            .WhereIF(instanceIds.Count > 0,
                (a, b, c, d) => instanceIds.Contains(a.InstanceNumber))
            .WhereIF(!string.IsNullOrEmpty(input.BuyerType), (a, b, c, d) => b.BuyerType.Contains(input.BuyerType))
            .WhereIF(!string.IsNullOrEmpty(input.CompanyCode), (a, b, c, d) => b.CompanyCode.Contains(input.CompanyCode))
            .WhereIF(!string.IsNullOrEmpty(input.BuyerCode), (a, b, c, d) => b.BuyerCode.Contains(input.BuyerCode))
            .WhereIF(!string.IsNullOrEmpty(input.CompanyName), (a, b, c, d) => b.CompanyName.Contains(input.CompanyName))
            .WhereIF(!string.IsNullOrEmpty(input.BuyerName), (a, b, c, d) => b.BuyerName.Contains(input.BuyerName))
            .WhereIF(!string.IsNullOrEmpty(input.RedLetterNumber), (a, b, c, d) => c.ApplyTaxNo.Contains(input.RedLetterNumber))
            .WhereIF(!string.IsNullOrEmpty(input.CreditMemoReason), (a, b, c, d) => b.CreditMemoReason.Contains(input.CreditMemoReason))
            .WhereIF(!string.IsNullOrEmpty(input.InvoiceNumber), (a, b, c, d) => a.InvoiceNumber.Contains(input.InvoiceNumber))
            .WhereIF(!string.IsNullOrEmpty(input.InvoiceCode), (a, b, c, d) => a.InvoiceCode.Contains(input.InvoiceCode))
            .WhereIF((input.CreditMemoAmountHasTax) != 0, (a, b, c, d) => a.CreditMemoAmountHasTax.Equals(input.CreditMemoAmountHasTax))
            .WhereIF((input.CreditMemoAmountNoTax) != 0, (a, b, c, d) => a.CreditMemoAmountNoTax.Equals(input.CreditMemoAmountNoTax))
            .WhereIF(!string.IsNullOrEmpty(input.SAPEntryVoucher), (a, b, c, d) => a.SAPEntryVoucher.Contains(input.SAPEntryVoucher))
            .WhereIF(!string.IsNullOrEmpty(input.RedInvoiceNumber), (a, b, c, d) => a.RedInvoiceNumber.Contains(input.RedInvoiceNumber))
            .WhereIF(!string.IsNullOrEmpty(input.RedInvoiceCode), (a, b, c, d) => a.RedInvoiceCode.Contains(input.RedInvoiceCode))
            .WhereIF(!string.IsNullOrEmpty(input.SapReceipt), (a, b, c, d) => a.SapReceipt.Contains(input.SapReceipt))
            .Select((a, b, c, d) => new GetBuyerScarletInformationOutput()
            {
                InstanceNumber = a.InstanceNumber,
                ProcessStartUserName = d.StartUserName,
                OrderStatus = d.ProcessStatusName,
                ProcessStartTime = d.StartTime,
                InvoiceCode = a.InvoiceCode,
                InvoiceNumber = a.InvoiceNumber,
                BuyerCode = b.BuyerCode,
                BuyerName = b.BuyerName,
                BuyerType = b.BuyerType,
                CompanyCode = b.CompanyCode,
                CompanyName = b.CompanyName,
                CreditMemoAmountHasTax = a.CreditMemoAmountHasTax,
                CreditMemoAmountNoTax = a.CreditMemoAmountNoTax,
                CreditMemoReason = b.CreditMemoReason,
                RedInvoiceCode = a.RedInvoiceCode,
                RedInvoiceDate = a.RedInvoiceDate,
                RedInvoiceNumber = a.RedInvoiceNumber,
                RedLetterNumber = c.ApplyTaxNo,
                SAPEntryVoucher = a.SAPEntryVoucher,
                SapReceipt = a.SapReceipt,
            });

            return listQueryable;

        }
    }
}